﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TD.bom
{
    public class Monster : MapObject
    {
        /// <summary>
        /// Position Z des cases
        /// </summary>
        public const int MonsterPositionZ = 2;


        protected _2dAcceleratedObject m_movement;

        #region Propriétés

        /// <summary>
        /// Nombre de points de vie
        /// </summary>
        public int HP { get; private set; }

        /// <summary>
        /// Armure
        /// </summary>
        public int Armor
        {
            get
            {
                return ((MonsterTemplate)Template).Armor;
            }
        }

        /// <summary>
        /// Vitesse de déplacement en case(si si) / s
        /// </summary>
        public double Speed
        {
            get
            {
                return ((MonsterTemplate)Template).Speed;
            }
        }

        /// <summary>
        /// Montant rapporté par le monstre une fois abatu
        /// </summary>
        public int Price
        {
            get
            {
                return ((MonsterTemplate)Template).Price;
            }
        }

        /// <summary>
        /// Point de passage vers lequel se dirige se monstre
        /// </summary>
        public WayPoint TargetWayPoint
        {
            get;
            protected set;
        }

        /// <summary>
        /// Indique si ce mostre est en jeu
        /// </summary>
        public bool InGame
        {
            get;
            set;
        }

        #endregion

        /// <summary>
        /// Construit un ... à partir de sont template
        /// </summary>
        /// <param name="p_map">Carte d'appartenance</param>
        /// <param name="p_templateName">Nom du template</param>
        public Monster(Map p_map, string p_templateName)
            : base(p_map, p_templateName)
        {
            // Chargement du template
            Template = MonsterTemplate.Get(p_templateName);

            // Initialisations à partir du template
            
            // Points de vie
            HP = ((MonsterTemplate)Template).HP;

            // Taille
            Size.Width = ((MonsterTemplate)Template).Size.Width;
            Size.Height = ((MonsterTemplate)Template).Size.Height;

            // Pour le moement le monstre n'est pas en jeu
            InGame = false;

            // Plan d'existance 
            Position.Z =  Monster.MonsterPositionZ;
        }

        /// <summary>
        /// Lance un monstre
        /// </summary>
        public void Go()
        {
            // On récupère le point départ
            WayPoint l_startingWP = Map.WayPoints[0];
            
            // et celui de destination
            TargetWayPoint = Map.WayPoints[1];
            
            // On centre le monstre sur la case de départ
            Position.X = l_startingWP.Position.X;
            Position.Y = l_startingWP.Position.Y;
            
            // On construit son gestionnaire de mouvement pour l'envoyer vers sa destination
            m_movement = new _2dAcceleratedObject(Position, TargetWayPoint.Position, Speed * Map.CaseSize.Width, new System.Windows.Point(0, 0));

            // Ce monstre est entré en jeu
            InGame = true;

            // Ajout au rendu du jeu
            Game.Instance.Renderer.AddObject(this);
        }

        /// <summary>
        /// Indique au monstre d'effectuer son déplacement
        /// </summary>
        public void Move()
        {
            // On récupère la nouvelle position grâce au gestionnaire de mouvement
            Position = m_movement.GetNextPosition();

            // On vérifie s'il a atteint le point de passage suivant
            if (HasReachedTargetWayPoint())
            {
                // Oui, était-ce le dernier ?
                int l_targetWayPointIndex = Map.WayPoints.IndexOf(TargetWayPoint);
                if (l_targetWayPointIndex == Map.WayPoints.Count - 1)
                {
                    // Oui, le monstre indique qu'il est arrivé

                    // et il sort du jeu
                    InGame = false;

                    // avec retrait du rendu du jeu
                    Game.Instance.Renderer.RemoveObject(this);
                }
                else
                {
                    // non, il faut donc passer au point de passage suivant
                    TargetWayPoint = Map.WayPoints[l_targetWayPointIndex + 1];
                    m_movement.GoTo(TargetWayPoint.Position, Speed * Map.CaseSize.Width, new System.Windows.Point(0, 0));
                }
            }
        }

        /// <summary>
        /// Indique si le mostre a atteint son point de passage cible
        /// </summary>
        /// <returns>true s'il l'a atteint, false sinon</returns>
        private bool HasReachedTargetWayPoint()
        {
            // On considère qu'à moins de 3 pixels, le monstre a atteint sa cible
            if (Position.GetSquaredDistanceXYFrom(TargetWayPoint.Position) < 3)
            {
                return true;
            }

            return false;
        }

        
    }
}
